package com.zj.eswrapper.interfaces;


import com.zj.eswrapper.model.Order;
import com.zj.eswrapper.model.Range;

import java.util.Arrays;
import java.util.Collection;
import java.util.Objects;
import java.util.function.Consumer;
import java.util.function.Supplier;

/**
 * es聚合条件拼接器接口
 *
 * @author 19242
 */
public interface IEsAggWrapper<Field, AggWrapper extends IEsAggWrapper<Field, AggWrapper, QueryWrapper, SearchBuilder, AggBuilder>, QueryWrapper, SearchBuilder, AggBuilder>
        extends IBaseWrapper<Field> {

    /**
     * 分组统计
     * field,count(*) group by field
     *
     * @param name  聚合名
     * @param field 聚合字段
     * @return 聚合完毕的返回的对象
     */
    default IEsAggNestWrapper<AggWrapper> terms(String name, Field field) {
        return terms(name, field, (Order) null);
    }

    /**
     * 分组统计
     * field,count(*) group by field
     *
     * @param name  聚合名
     * @param field 聚合字段
     * @param size  返回值
     * @return 聚合完毕的返回的对象
     */
    default IEsAggNestWrapper<AggWrapper> terms(String name, Field field, Integer size) {
        return terms(name, field, size, (Order) null);
    }

    /**
     * 分组统计
     * field,count(*) group by field
     *
     * @param name   聚合名
     * @param field  聚合字段
     * @param orders 排序
     * @return 聚合完毕的返回的对象
     */
    default IEsAggNestWrapper<AggWrapper> terms(String name, Field field, Order... orders) {
        return terms(name, field, null, orders);
    }

    /**
     * 分组统计
     * field,count(*) group by field
     *
     * @param name   聚合名
     * @param field  聚合字段
     * @param size   返回值
     * @param orders 排序
     * @return 聚合完毕的返回的对象
     */
    IEsAggNestWrapper<AggWrapper> terms(String name, Field field, Integer size, Order... orders);

    /**
     * 统计
     * count(field)
     *
     * @param name  聚合名
     * @param field 聚合字段
     * @return 聚合完毕的返回的对象
     */
    IEsAggNestWrapper<AggWrapper> count(String name, Field field);

    /**
     * 去重统计
     * count(distinct field)
     *
     * @param name  聚合名
     * @param field 聚合字段
     * @return 聚合完毕的返回的对象
     */
    IEsAggNestWrapper<AggWrapper> cardinality(String name, Field field);

    /**
     * 平均值
     * avg(field)
     *
     * @param name  聚合名
     * @param field 聚合字段
     * @return 聚合完毕的返回的对象
     */
    IEsAggNestWrapper<AggWrapper> avg(String name, Field field);

    /**
     * 值相加
     * sum(field)
     *
     * @param name  聚合名
     * @param field 聚合字段
     * @return 聚合完毕的返回的对象
     */
    IEsAggNestWrapper<AggWrapper> sum(String name, Field field);

    /**
     * 最大值
     * min(field)
     *
     * @param name  聚合名
     * @param field 聚合字段
     * @return 聚合完毕的返回的对象
     */
    IEsAggNestWrapper<AggWrapper> max(String name, Field field);

    /**
     * 最小值
     * min(field)
     *
     * @param name  聚合名
     * @param field 聚合字段
     * @return 聚合完毕的返回的对象
     */
    IEsAggNestWrapper<AggWrapper> min(String name, Field field);

    /**
     * 详细信息
     * count(field),avg(field),sum(field),min(field),min(field)
     *
     * @param name  聚合名
     * @param field 聚合字段
     * @return 聚合完毕的返回的对象
     */
    IEsAggNestWrapper<AggWrapper> stats(String name, Field field);

    /**
     * 过滤
     *
     * @param name     聚合名
     * @param consumer 查询拼接器
     * @return 聚合完毕的返回的对象
     */
    IEsAggNestWrapper<AggWrapper> filter(String name, Consumer<QueryWrapper> consumer);

    /**
     * 区间聚合
     *
     * @param name   聚合名
     * @param field  聚合字段
     * @param ranges 区间
     * @return 聚合完毕的返回的对象
     */
    default IEsAggNestWrapper<AggWrapper> range(String name, Field field, Range... ranges) {
        return range(name, field, Objects.nonNull(ranges) ? Arrays.asList(ranges) : null);
    }

    /**
     * 区间聚合
     *
     * @param name   聚合名
     * @param field  聚合字段
     * @param ranges 区间
     * @return 聚合完毕的返回的对象
     */
    IEsAggNestWrapper<AggWrapper> range(String name, Field field, Collection<Range> ranges);

    /**
     * 自定义条件拼接
     *
     * @param name  聚合名，es6要在query里赋值，此处name无效
     * @param query 查询函数
     * @return 聚合完毕的返回的对象
     */
    default IEsAggNestWrapper<AggWrapper> custom(String name, Supplier<AggBuilder> query) {
        return custom(name, Objects.nonNull(query) ? query.get() : null);
    }

    /**
     * 自定义条件拼接
     *
     * @param name    聚合名，es6要在query里赋值，此处name无效
     * @param builder 查询类
     * @return 聚合完毕的返回的对象
     */
    IEsAggNestWrapper<AggWrapper> custom(String name, AggBuilder builder);

    /**
     * 添加拼接的条件
     *
     * @param searchBuilder searchBuilder
     */
    void addAgg(SearchBuilder searchBuilder);
}
